home *** CD-ROM | disk | FTP | other *** search
- /* ======================================= *
- file: BitMapper_main.c
- version: 2
- date: 11.13.89
- * --------------------------------------- *
- Copyright © 1989, Michael Ogawa and
- MacTutor — All Rights Reserved.
- * ======================================= */
-
- /* #include <MacHeaders> */
- #include "BitMapper.h"
-
- #ifdef applec
- # include <Desk.h>
- # include <Scrap.h>
- # include <Packages.h>
- typedef char SignedByte;
- #endif applec
-
-
- /* Code resource entry point (MPW) ======= */
-
- #ifdef applec
- pascal void BitMapper(short selector,
- MenuDataPtr toolInfo, long *refCon,
- short *returnCode)
- /* Code resource entry point for a
- SuperPaint transformation command plug-in
- tool built in MPW C. This avoids having to
- forward reference all the internal
- routines. */
- /* m_o 06.23.89 */
- {
- main(selector, toolInfo, refCon,
- returnCode);
- }
- #endif applec
-
-
- /* private functions ===================== */
-
- static short OpenOutput(
- TBitMapperPtr pMyInfo)
- /* Prepares the appropriate output method.
- PMyInfo is a pointer to a BitMapper record
- containing information about the currently
- executing command.
- This version of OpenOutput() simply
- prepares output to the desk scrap. The
- clipboard is cleared, and as a workaround for
- MultiFinder’s selective updating of other
- partitions’ ScrapCount low-memory variable,
- SystemEdit() is called with the copy message.
- (See “Macintosh Technical Note #180:
- MultiFinder Miscellanea” for details.)
- If no error occured then the result code
- noErr is returned as the function return
- value; otherwise an appropriate Operating
- System result code is returned as the
- function return value. */
- /* m_o 11.13.89 */
- {
- # pragma unused(pMyInfo)
-
- /* MultiFinder work-around: notify
- System of copy operation… */
- (void)SystemEdit(3);
- /* clear the desk scrap… */
- return(ZeroScrap());
- }
-
-
- static short DoOutput(Handle hData,
- ResType rType, TBitMapperPtr pMyInfo)
- /* Outputs the data in the relocatable
- block specified by the handle hData. The
- data output format is specified by rType.
- PMyInfo is a pointer to a BitMapper record
- containing information about currently
- executing command.
- This version of DoOutput() simply sends
- the data to the clipboard using the Toolbox
- routine PutScrap(), specifying rType as the
- Desk scrap data type. Note that it does not
- call ZeroScrap(), so the output is added to
- the current scrap content as an additional
- type. This is not good if the scrap already
- contains a resource of the specified type.
- Therefore, ZeroScrap() should be called once
- before outputting any data to the scrap.
- If no error occured then the result code
- noErr is returned as the function return
- value; otherwise an appropriate Operating
- System result code is returned as the
- function return value. */
- /* m_o 11.13.89 */
- {
- # pragma unused(pMyInfo)
- SignedByte savedMPFlags;
- short result;
-
- /* get master pointer flags and lock down… */
- savedMPFlags = HGetState(hData);
- MoveHHi(hData);
- HLock(hData);
-
- result = PutScrap(GetHandleSize(hData),
- rType, *hData);
-
- /* restore master pointer state… */
- HSetState(hData, savedMPFlags);
-
- return(result);
- }
-
-
- static void CopyBits2Buffer(
- const BitMap *pSrcBMap,
- const Rect *pSrcRect, Ptr pBuffer,
- short bufferRowBytes, short mode)
- /* Transfers a bit image specified by the
- bit map *pSrcMap to the image buffer
- pBuffer[]. The image buffer must begin on an
- even address. The width, in bytes, of the
- destination buffer is specified by
- bufferRowBytes, which must also be even.
- The bits enclosed by the source
- rectangle *pSrcRect are transferred to a
- similar sized rectangle in the destination
- image. The destination rectangle is the same
- size as the source rectangle and is aligned
- at the top left corner of the destination bit
- image. The destination image buffer must be
- big enough to accomodate the entire image
- being transferred. The transfer mode is
- specified by the mode parameter. */
- /* m_o 06.22.89 */
- {
- BitMap dstBMap;
-
- dstBMap.baseAddr = pBuffer;
- dstBMap.rowBytes = bufferRowBytes;
- dstBMap.bounds = *pSrcRect;
- CopyBits(pSrcBMap, &dstBMap, pSrcRect,
- pSrcRect, mode, NULL);
- }
-
-
- static short PutPICT(TBitMapperPtr pMyInfo)
- /* Makes a picture that is a copy of the
- selection area our command is working with,
- then outputs the picture. PMyInfo is a
- pointer to a BitMapper record containing
- information about currently executing
- command. This includes a grafPtr to the
- document port (which is also the current
- port).
- Before calling us, SuperPaint has
- already set the port’s portRect to be
- equivalent to the selection bounding
- rectangle in a coordinate system local to the
- selection. That is, portRect.topLeft is
- (0,0), portRect.bottom is equal to the height
- of the selection area, and portRect.right is
- equal to the width of the selection area.
- If no error occured then the result code
- noErr is returned as the function return
- value; otherwise an appropriate Operating
- System result code is returned as the
- function return value. */
- /* m_o 09.13.89 */
- {
- short result;
- PicHandle hMyPic;
-
- if (hMyPic = OpenPicture(
- &pMyInfo->drawGptr->portRect)) {
- /* copy selection… */
- CopyBits(
- &pMyInfo->drawGptr->portBits,
- &pMyInfo->drawGptr->portBits,
- &pMyInfo->drawGptr->portRect,
- &pMyInfo->drawGptr->portRect,
- srcCopy, NULL);
- ClosePicture();
- result = DoOutput((Handle)hMyPic,
- 'PICT', pMyInfo);
- KillPicture(hMyPic);
- } else
- result = MemError();
- return(result);
- }
-
-
- static short PutBTMP(TBitMapperPtr pMyInfo)
- /* Makes a 'BTMP' resource from the
- selection area our command is working with,
- then outputs the resource. PMyInfo is a
- pointer to a BitMapper record containing
- information about the currently executing
- command. This includes a grafPtr to the
- document port (which is also the current
- port).
- Before calling us, SuperPaint has
- already set the port’s portRect to be
- equivalent to the selection bounding
- rectangle in a coordinate system local to the
- selection. That is, portRect.topLeft is
- (0,0), portRect.bottom is equal to the height
- of the selection area, and portRect.right is
- equal to the width of the selection area.
- If no error occured then the result code
- noErr is returned as the function return
- value; otherwise an appropriate Operating
- System result code is returned as the
- function return value. */
- /* m_o 09.17.89 */
- {
- long sz;
- short result;
- BitMap myMap;
- TBTMPPkHndl hMyBTMP;
-
- /* set up BitMap: init baseAddr… */
- myMap.baseAddr = NULL;
- /* get bounds rectangle… */
- myMap.bounds =
- pMyInfo->drawGptr->portRect;
- /* calc rowBytes… */
- myMap.rowBytes =
- BITS2ROWBYTES(WIDTH(myMap.bounds));
- /* calc size of 'BTMP' resource… */
- sz = sizeof(TBTMP) +
- myMap.bounds.bottom *
- myMap.rowBytes;
-
- /* get ‘clean’ memory for new
- 'BTMP' resource… */
- if (!(hMyBTMP =
- (TBTMPPkHndl)NewHandleClear(sz)))
- return(MemError());
-
- /* copy BitMap… */
- (**hMyBTMP).map = myMap;
-
- /* copy bit image… */
- MoveHHi((Handle)hMyBTMP);
- HLock((Handle)hMyBTMP);
- CopyBits2Buffer(
- &pMyInfo->drawGptr->portBits,
- &myMap.bounds,
- (Ptr)&(**hMyBTMP).image,
- myMap.rowBytes, srcCopy);
- HUnlock((Handle)hMyBTMP);
-
- /* ship it! */
- result = DoOutput((Handle)hMyBTMP,
- 'BTMP', pMyInfo);
-
- /* clean up and leave… */
- DisposHandle((Handle)hMyBTMP);
- return(result);
- }
-
-
- static short PutBTMN(TBitMapperPtr pMyInfo)
- /* Makes a 'BTM#' resource from the
- selection area our command is working with,
- then outputs the resource. PMyInfo is a
- pointer to a BitMapper record containing
- information about the currently executing
- command. This includes a grafPtr to the
- document port (which is also the current
- port).
- Before calling us, SuperPaint has
- already set the port’s portRect to be
- equivalent to the selection bounding
- rectangle in a coordinate system local to the
- selection. That is, portRect.topLeft is
- (0,0), portRect.bottom is equal to the height
- of the selection area, and portRect.right is
- equal to the width of the selection area.
- If no error occured then the result code
- noErr is returned as the function return
- value; otherwise an appropriate Operating
- System result code is returned as the
- function return value. */
- /* m_o 11.17.89 */
- {
- long sz;
- short result;
- BitMap myMap;
- TBTMNHndl hMyBTMN;
- TBTMNEntryPtr pMyBTMNEntry;
-
- /* set up BitMap: init baseAddr… */
- myMap.baseAddr = NULL;
- /* get bounds rectangle… */
- myMap.bounds =
- pMyInfo->drawGptr->portRect;
- /* calc rowBytes… */
- myMap.rowBytes =
- BITS2ROWBYTES(WIDTH(myMap.bounds));
- /* calc size of 'BTMP' resource… */
- sz = sizeof(TBTMP) +
- myMap.bounds.bottom *
- myMap.rowBytes;
-
- /* get ‘clean’ memory for new
- 'BTM#' resource… */
- if (!(hMyBTMN =
- (TBTMNHndl)NewHandleClear(sz +
- sizeof((**hMyBTMN).count) +
- sizeof((**hMyBTMN).
- theBTMNEntries[0].szEntry))))
- return(MemError());
-
- /* number of BTMP entries… */
- (**hMyBTMN).count = 1;
- /* lock, get pointer to entry… */
- MoveHHi((Handle)hMyBTMN);
- HLock((Handle)hMyBTMN);
- pMyBTMNEntry =
- (**hMyBTMN).theBTMNEntries;
- /* size of the BTM# entry… */
- pMyBTMNEntry->szEntry =
- sizeof(pMyBTMNEntry->szEntry) + sz;
- /* copy BitMap… */
- pMyBTMNEntry->theBTMP.map = myMap;
- /* copy bit image… */
- CopyBits2Buffer(
- &pMyInfo->drawGptr->portBits,
- &myMap.bounds,
- (Ptr)pMyBTMNEntry->theBTMP.image,
- myMap.rowBytes, srcCopy);
- HUnlock((Handle)hMyBTMN);
-
- /* ship it! */
- result = DoOutput((Handle)hMyBTMN,
- 'BTM#', pMyInfo);
-
- /* clean up and leave… */
- DisposHandle((Handle)hMyBTMN);
- return(result);
- }
-
-
- static short DoIt(TBitMapperPtr pMyInfo)
- /* Makes a 'BTMP' or 'BTM#' resource and a
- picture from the selection area our command
- is working with, then outputs the resources.
- PMyInfo is a pointer to a BitMapper record
- containing information about currently
- executing command. All its fields should be
- filled in on entry, except the drawGptr field
- which this routine fills in. (The drawGptr
- field is a grafPtr to the document port,
- which is also the current port.)
- The menuItem field of the menu command
- data record specified by the BitMapper record
- specifies whether to create a 'BTMP' or 'BTM#'
- resource.
- If no error occured then the result code
- noErr is returned as the function return
- value; otherwise an appropriate Operating
- System result code is returned as the
- function return value. */
- /* m_o 11.17.89 */
- {
- short result;
-
- GetPort(&pMyInfo->drawGptr);
- if ((result = OpenOutput(pMyInfo)) ==
- noErr) {
- short result2;
-
- result =
- (pMyInfo->pToolInfo->menuItem
- == kMITEM_BTMP) ?
- PutBTMP(pMyInfo) :
- PutBTMN(pMyInfo);
- if ((result2 = PutPICT(pMyInfo)) !=
- noErr && result == noErr)
- result = result2;
- }
- return(result);
- }
-
-
- static void AlertErr(short err,
- short baseID)
- /* Puts up an alert telling the user an
- error occured. Err is the result code of
- the error. This is converted to a string
- and substituted for param text ^0 in the
- alert.
- BaseID is the resource ID of the first
- (numerically lowest) resource in our plug-in
- tool. Because resource IDs may be
- reassigned, we calculate our alert’s current
- resource ID based on this. */
- /* m_o 09.30.89 */
- {
- Str255 s;
- unsigned char str0 = '\0';
-
- /* Convert error ID to string format,
- put into param text ^0. Note usage
- of “str0” because we can’t have any
- globals. Not even empty strings! */
- NumToString(err, s);
- ParamText(s, &str0, &str0, &str0);
- /* The following line would be illegal!!
- ParamText(s, "", "", ""); */
-
- CenterWindow('ALRT',
- baseID + kALRT_Err);
- /* make sure cursor is arrow… */
- InitCursor();
-
- NoteAlert(baseID + kALRT_Err, NULL);
- }
-
- /* entry points ========================== */
-
- pascal void main(short selector,
- MenuDataPtr toolInfo, long *refCon,
- short *returnCode)
- /* Entry point and command dispatcher for
- the BitMapper plug-in command tool. Selector
- is a call type code as defined by Silicon
- Beach Software in the Menu Command Interface
- section of their plug-in documentation
- “Developing Plug-In Modules for SuperPaint”.
- */
- /* m_o 08.29.89 */
- {
- TBitMapperRec myInfo;
-
- switch (selector) {
- case menuAbout:
- /* tell SuperPaint we have TEXT
- resource for About Box info… */
- *returnCode = textAbout;
- break;
- case menuOptions:
- /* tell SuperPaint we don’t need
- a scratch buffer… */
- ((MenuOptionsPtr)toolInfo)->
- usesScratch = false;
- *returnCode = noErr;
- break;
- case menuSelected:
- /* setup private data record
- and do it!… */
- myInfo.pToolInfo = toolInfo;
- myInfo.pRefCon = refCon;
- *returnCode = DoIt(&myInfo);
- break;
- }
-
- /* alert user on errors… */
- if (*returnCode != noErr &&
- selector != menuAbout)
- AlertErr(*returnCode,
- toolInfo->toolID);
- return;
- }
-